<!-- 有控件的导出 -->
<template>
  <a-modal
    :width="'80%'"
    :visible="dialogVisible"
    @ok="handleOk"
    @cancel="handleCancel"
    unmountOnClose
    title-align="center"
  >
    <template #title> {{ props.title }} </template>

    <div class="wrap">
      <div class="wrap-unused">
        <a-scrollbar style="height: 600px; overflow: auto">
          <a-space direction="vertical">
            <h3>可选字段</h3>
            <a-checkbox
              :model-value="checkedAll"
              :indeterminate="indeterminate"
              @change="handleChangeAll"
              >全选
            </a-checkbox>
            <div v-for="item in headerList.list" :key="item.ctlCode">
              <h3>{{ item.collectionName }}</h3>
              <a-checkbox-group @change="onChange" v-model="selectedData">
                <a-checkbox
                  v-for="controls in item.heads"
                  :key="controls.ctlCode"
                  :value="controls.ctlCode"
                  :disabled="
                    forbidList?.includes(controls.ctlCode) ||
                    forbidSelectedList?.includes(controls.ctlCode)
                  "
                >
                  {{ controls.ctlCnName }}
                </a-checkbox>
              </a-checkbox-group>
            </div>
          </a-space>
        </a-scrollbar>
      </div>
      <div class="wrap-used">
        <a-scrollbar style="height: 600px; overflow: auto">
          <div class="draggable-selected">
            <h3>已选字段</h3>
            <draggable
              class="item"
              :list="selectedHeader.list"
              ghost-class="ghost"
              handle=".move"
              filter=".forbid"
              :force-fallback="true"
              chosen-class="chosenClass"
              animation="300"
              :fallback-class="true"
              :fallback-on-body="true"
              :touch-start-threshold="10"
              :fallback-tolerance="10"
              :sort="true"
              itemKey="code"
            >
              <template #item="{ element }">
                <a-space direction="vertical" class="item-box" :size="16">
                  <div class="item-box-container move">
                    <icon-font
                      type="icon-a-Dragtuozhuai"
                      :size="16"
                    ></icon-font>
                    <span
                      :style="{
                        marginLeft: '10px'
                      }"
                    >
                      {{ element.ctlCnName }}
                    </span>
                    <icon-font
                      type="icon-a-Close-smallguanbi-xiao"
                      :size="20"
                      @click="removeHeader(element)"
                      v-if="forbidList.includes(element.ctlCode) ? false : true"
                      :style="{
                        float: 'right',
                        transform: 'translateY(-50%)',
                        margin: '25px 10px 0px 0px',
                        cursor: 'pointer'
                      }"
                    ></icon-font>
                  </div>
                </a-space>
              </template>
            </draggable>
          </div>
        </a-scrollbar>
      </div>
    </div>
  </a-modal>
</template>

<script lang="ts" setup>
import { reactive, ref, computed, watch, watchEffect } from 'vue';
import { formHeaderSetting } from '@/types/global';
import Draggable from 'vuedraggable';
import cloneDeep from 'lodash.clonedeep';

const props = withDefaults(
  // 参数说明
  defineProps<{
    visible: boolean; // 判断是否打开表头设置抽屉
    title: string; // 标题

    /* 
      filedName: string;
      name: string;
      isDefault: boolean;
      sort: number;
    */
    resultList: any; // 传过来的表头
    forbidList?: string[]; // 不准移动和删除的表头
    forbidSelectedList?: string[]; // 禁止选择的表头
    // listData: () => any; // 请求表头的数据
  }>(),
  {
    visible: false,
    title: '表头设置',
    resultList: () => [],
    forbidList: () => []
  }
);

const emits = defineEmits(['update:visible', 'headerSave']);

// 单个表头接口
type Iheader = {
  id?: number; // id
  ctlCode: string; // 控件编码
  isDefault: boolean; // 是否选择表头
  code: string; // 表头编号
  name: string; // 表头名称
};

// 判断抽屉是否显示
const dialogVisible = computed({
  get() {
    return props.visible;
  },
  set(visible: boolean) {
    emits('update:visible', visible);
  }
});

const checkedAll = ref(false); // 判断是否全选
const indeterminate = ref(false);
let selectedData: any = ref([]); // 储存多选框选中的值
// 所有表头
const headerList: any = reactive({
  list: []
});

// 未选择的表头
const unselectedHeaders: any = reactive({
  list: []
});

// 选择的表头
const selectedHeader: any = reactive({
  list: []
});

// 判断全选按钮的状态;
const isIndeterminate = () => {
  if (!props.forbidSelectedList) {
    if (selectedData.value.length === tempArr.value.length) {
      checkedAll.value = true;
      indeterminate.value = false;
    } else if (selectedData.value.length === 0) {
      checkedAll.value = false;
      indeterminate.value = false;
    } else {
      checkedAll.value = false;
      indeterminate.value = true;
    }
  } else {
    if (
      selectedData.value.length + props.forbidSelectedList?.length ===
      tempArr.value.length
    ) {
      checkedAll.value = true;
      indeterminate.value = false;
    } else if (selectedData.value.length === 0) {
      checkedAll.value = false;
      indeterminate.value = false;
    } else {
      checkedAll.value = false;
      indeterminate.value = true;
    }
  }
};

// 将选中的表头排序
const quickSort = (arr: any): any => {
  if (arr.length <= 1) return arr;
  const num = arr[0];
  let left = [],
    right = [];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i].sort <= num.sort) left.push(arr[i]);
    else right.push(arr[i]);
  }
  return [...quickSort(left), num, ...quickSort(right)];
};

let tempArr: any = ref([]); // 储存所有表头
watch(
  dialogVisible,
  (newVal, oldVal) => {
    if (newVal) {
      // headerList.list = cloneDeep([
      //   ...props.resultList.used,
      //   ...props.resultList.unused
      // ]);
      headerList.list = cloneDeep(props.resultList);
    } else headerList.list = [];
  },
  {
    immediate: true
  }
);

watchEffect(() => {
  // unselectedHeaders.list = headerList.list.filter(
  //   (item: any) => item.isDefault === false
  // );
  // selectedHeader.list = headerList.list.filter(
  //   (item: any) => item.isDefault === true
  // );
  unselectedHeaders.list = [];
  selectedHeader.list = [];

  tempArr.value = [];
  headerList.list.forEach((item1: any) => {
    unselectedHeaders.list = [
      ...unselectedHeaders.list,
      ...item1.heads.filter(
        (item2: any) =>
          item2.isDefault === false ||
          props.forbidSelectedList?.includes(item2.ctlCode)
      )
    ];
    selectedHeader.list = [
      ...selectedHeader.list,
      ...item1.heads.filter(
        (item2: any) =>
          !props.forbidSelectedList?.includes(item2.ctlCode) &&
          item2.isDefault === true
      )
    ];
  });
  tempArr.value = [...selectedHeader.list, ...unselectedHeaders.list];

  selectedData.value = [];
  selectedHeader.list.forEach((item: any) => {
    if (!props.forbidSelectedList?.includes(item.ctlCode))
      selectedData.value.push(item.ctlCode);
    // selectedData.value.push(item.id);
  });
  selectedHeader.list = quickSort(selectedHeader.list);
  isIndeterminate();
});

// 全选事件
const handleChangeAll = (value: boolean) => {
  indeterminate.value = false;
  if (value) {
    selectedData.value = [];
    checkedAll.value = true;
    headerList.list.forEach((item: any) => {
      item.heads.forEach((item2: any) => {
        item2.isDefault = true;
        selectedData.value.push(item2.ctlCode);
      });
    });
  } else {
    checkedAll.value = false;
    headerList.list.forEach((item: any) => {
      item.heads.forEach((item2: any) => {
        if (props.forbidList.includes(item2.ctlCode)) item2.isDefault = true;
        else item2.isDefault = false;
      });
    });
    selectedData.value = [];
  }
};

// 点击非全选框时
const onChange = (val: any) => {
  isIndeterminate();
  console.log('val', val);

  headerList.list.forEach((item: any) => {
    item.heads.forEach((item2: any) => {
      if (val.includes(item2.ctlCode)) item2.isDefault = true;
      else item2.isDefault = false;
    });
  });
};

// 去除一个表头
const removeHeader = (header: Iheader) => {
  headerList.list.forEach((item1: any) => {
    item1.heads.forEach((item2: any) => {
      if (item2.ctlCode === header.ctlCode) {
        item2.isDefault = false;
        const index = selectedData.value.findIndex(
          (item3: any) => item3.ctlCode === header.ctlCode
        );
        selectedData.value.splice(index, 1);
        console.log(selectedData.value);
        isIndeterminate();
      }
    });
  });
};

// 确认
const handleOk = () => {
  // 排序
  selectedHeader.list.forEach((item: any, index: number) => {
    item.sort = index;
  });
  // 获取当前用户的id
  const userId: any = +(localStorage.getItem('userId') as string);
  emits('headerSave', selectedHeader.list, userId);
  dialogVisible.value = false;
};

// 取消
const handleCancel = () => {
  dialogVisible.value = false;
};
</script>

<style scoped lang="less">
.wrap {
  display: flex;
  justify-content: space-between;

  &-unused {
    flex: 4;
    border: 1px solid #ccc;
    margin-right: 10px;
    height: 600px;
    padding: 10px;
  }

  &-used {
    flex: 2;
    border: 1px solid #ccc;
    padding: 10px;
    .draggable {
      &-selected {
        padding-bottom: 20px;

        .item {
          &-box {
            width: 100%;
            &-container {
              // background-color: #f2f3f5;
              height: 50px;
              line-height: 50px;
            }
            &-container:hover {
              background-color: #f2f3f5;
            }
          }
        }
      }
      // &-unselected {
      //   .item {
      //     display: flex;
      //     flex-wrap: wrap;
      //     width: 100%;
      //     background-color: #4e5969;
      //     &-box {
      //       width: 100%;
      //       margin: 0 10px 10px 0;
      //       &-container {
      //         background-color: #f2f3f5;
      //       }
      //     }
      //   }
      // }
    }
  }
}
</style>
